#import "ALElementBarTextFieldCell.h"
#import "NSBezierPath+SMRAdditions.h"


#pragma mark Constants
static const CGFloat ALElementBarCornerRadius = 3.0f;
static const CGFloat ALElementBarLeftPadding = 2.0f;
static const CGFloat ALElementBarRightPadding = 4.0f;


#pragma mark Class variables
static NSColor *ALElementBarBorderColor;
static NSColor *ALElementBarBorderColorSelected;
static NSGradient *ALElementBarBackgroundGradient;
static NSGradient *ALElementBarBackgroundGradientSelected;


#pragma mark -
@interface ALElementBarTextFieldCell (ALElementBarTextFieldCellPrivateMethods)
-(NSBezierPath *)framePathWithRect_:(NSRect)frameRect;
@end


#pragma mark -
@implementation ALElementBarTextFieldCell

@synthesize selected;
@synthesize useRoundedBottom;


+(void)initialize {
	ALElementBarBorderColor = [[NSColor colorWithCalibratedWhite:0.783 alpha:1.000] retain];
	ALElementBarBorderColorSelected = [[NSColor colorWithCalibratedWhite:0.5f alpha:1.0f] retain];
	NSColor *backgroundTop = [NSColor colorWithCalibratedWhite:0.944 alpha:1.000];
	NSColor *backgroundBottom = [NSColor colorWithCalibratedWhite:1.000 alpha:1.000];
	ALElementBarBackgroundGradient = [[NSGradient alloc] initWithStartingColor:backgroundTop endingColor:backgroundBottom];
	NSColor *bottomSelected = [NSColor colorWithCalibratedRed:0.864 green:0.895 blue:0.926 alpha:1.000];
	NSColor *topSelected = [NSColor colorWithCalibratedRed:0.664 green:0.712 blue:0.833 alpha:1.000];
	ALElementBarBackgroundGradientSelected = [[NSGradient alloc] initWithStartingColor:topSelected endingColor:bottomSelected];
}

-(id)initTextCell:(NSString *)aString {
	if (!(self = [super initTextCell:aString]))
		return nil;
	[self setUseRoundedBottom:YES];
	return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder {
	if (!(self = [super initWithCoder:aDecoder]))
		return nil;
	[self setUseRoundedBottom:YES];
	return self;
}

-(void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
	NSRect borderRect = NSInsetRect(cellFrame, 0.5f, 0.5f);
	NSBezierPath *borderPath = [self framePathWithRect_:borderRect];
	NSGradient *backgroundGradient = [self selected] ? ALElementBarBackgroundGradientSelected : ALElementBarBackgroundGradient;
	[backgroundGradient drawInBezierPath:borderPath angle:270.0f];
	NSColor *borderColor = [self selected] ? ALElementBarBorderColorSelected : ALElementBarBorderColor;
	[borderColor setStroke];
	[borderPath stroke];
	
	if ([self showsFirstResponder] && [self focusRingType] != NSFocusRingTypeNone) {
		NSBezierPath *focusPath = [self framePathWithRect_:cellFrame];
		[NSGraphicsContext saveGraphicsState];
		NSSetFocusRingStyle(NSFocusRingOnly);
		[focusPath fill];
		[NSGraphicsContext restoreGraphicsState];
	}

	NSRect interiorRect = NSInsetRect(cellFrame, ALElementBarLeftPadding, 0.0f);
	[self drawInteriorWithFrame:interiorRect inView:controlView];
}

-(void)editWithFrame:(NSRect)cellFrame inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
	NSRect paddedFrame = NSInsetRect(cellFrame, ALElementBarLeftPadding, 0.0f);
	[super editWithFrame:paddedFrame inView:controlView editor:textObj delegate:anObject event:theEvent];
}

-(void)selectWithFrame:(NSRect)cellFrame inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength {
	NSRect paddedFrame = NSInsetRect(cellFrame, ALElementBarLeftPadding, 0.0f);
	[super selectWithFrame:paddedFrame inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
}

-(NSBezierPath *)framePathWithRect_:(NSRect)frameRect {
	CGFloat minx = NSMinX(frameRect);
	CGFloat maxx = NSMaxX(frameRect);
	CGFloat miny = NSMinY(frameRect);
	CGFloat maxy = NSMaxY(frameRect);
	CGFloat corner = ALElementBarCornerRadius;
	NSBezierPath *framePath = [NSBezierPath bezierPath];
	[framePath moveToPoint:NSMakePoint(maxx, miny)];
	[framePath lineToPoint:NSMakePoint(maxx, maxy)];
	if ([self useRoundedBottom]) {
		[framePath lineToPoint:NSMakePoint(minx + corner, maxy)];
		[framePath appendBezierPathWithArcFromPoint:NSMakePoint(minx, maxy) toPoint:NSMakePoint(minx, maxy - corner) radius:corner];
	}
	else 
		[framePath lineToPoint:NSMakePoint(minx, maxy)];
	[framePath lineToPoint:NSMakePoint(minx, miny + corner)];
	[framePath appendBezierPathWithArcFromPoint:NSMakePoint(minx, miny) toPoint:NSMakePoint(minx + corner, miny) radius:corner];
	[framePath closePath];
	return framePath;
}

@end
